import { _decorator, Component, Label, Node, Sprite, Graphics, Color, Vec2, Widget, Vec3 } from 'cc';
const { ccclass, property } = _decorator;
import { BilliardGame } from './BilliardGame';
import { Game } from '../core/Game';
import { ResourceManager } from '../framework/ResourceManager';
import { Databus } from '../core/Databus';
import { EventManager } from '../core/EventManager';
import { SoundManager } from '../framework/SoundManager';
const databus = Databus.Instance();

@ccclass('UserNavigation')
export class UserNavigation extends Component {
  private static MaxUserTime = 60;
  private selfComponent: Node = null;
  private oppoComponent: Node = null;
  private selfHitBallName: Node = null;
  private oppoHitBallName: Node = null;
  private selfScore: Node = null;
  private oppoScore: Node = null;

  private selfUserName: Label = null;
  private oppoUserName: Label = null;

  private selfUserHeaderImage: Sprite = null;
  private oppoUserHeaderImage: Sprite = null;
  private pos: Vec3 = new Vec3();
  private selfScorePos = new Vec3();
  private oppoScorePos = new Vec3();
  private scoreTime = 1000;
  private scoreSide = 0;
  private scoreDiff = 0;
  private countDown = 0;
  onLoad() {
    this.selfComponent = this.node.getChildByName('SelfComponent');
    this.oppoComponent = this.node.getChildByName('OppoComponent');

    this.selfHitBallName = this.node.getChildByName('SelfComponent').getChildByName('HitBallName');
    this.oppoHitBallName = this.node.getChildByName('OppoComponent').getChildByName('HitBallName');
  
    this.selfScore = this.node.getChildByName('SelfComponent').getChildByName('CurrentScore');
    this.oppoScore = this.node.getChildByName('OppoComponent').getChildByName('CurrentScore');

    this.selfUserName = this.node.getChildByName('SelfComponent').getChildByName('UserNickName').getComponent(Label);
    this.oppoUserName = this.node.getChildByName('OppoComponent').getChildByName('UserNickName').getComponent(Label);
  
    this.selfUserHeaderImage = this.node.getChildByName('SelfComponent').getChildByName('UserHeaderImage').getComponent(Sprite);
    this.oppoUserHeaderImage = this.node.getChildByName('OppoComponent').getChildByName('UserHeaderImage').getComponent(Sprite);

    EventManager.Instance().AddEventListener('AddUserScore', this, this.addUserScore);

    this.selfScore.getChildByName('Text').getPosition(this.selfScorePos);
    this.oppoScore.getChildByName('Text').getPosition(this.oppoScorePos);
    this.aliginMargin();
    this.scoreTime = 1000;
  }
  aliginMargin() {
    const selfWidget = this.selfComponent.getComponent(Widget);
    selfWidget.left = databus.sceenSize.alignMargin() - 10;
    const oppoWidget = this.oppoComponent.getComponent(Widget);
    oppoWidget.right = databus.sceenSize.alignMargin() - 10;
  }

  onEnable () {

  }

  update(deltaTime: number) {
    if (Game.Instance().status.isEnded()) {
      return;
    }
    this.scoreTime += 1;
    this.hideOppoCommponent();
    this.selfUserName.string = Game.Instance().playUsers[0].userAttribute.showNickName();
    this.oppoUserName.string = Game.Instance().playUsers[1].userAttribute.showNickName();
    const ssp = ResourceManager.Instance().getImageSpriteFrame(ResourceManager.SelfUserHeaderImage);
    if (ssp) {
      this.selfUserHeaderImage.spriteFrame = ssp;
    }
    const osp = ResourceManager.Instance().getImageSpriteFrame(ResourceManager.OppoUserHeaderImage);
    if (osp) {
      this.oppoUserHeaderImage.spriteFrame = osp;
    }
    // 击球信息
    const stext = this.selfHitBallName.getComponent(Label);
    stext.string = BilliardGame.Instance().getUserHitColorText(Game.Instance().playUsers[0].color);
    const otext = this.oppoHitBallName.getComponent(Label);
    otext.string = BilliardGame.Instance().getUserHitColorText(Game.Instance().playUsers[1].color);
    
    this.updateScore();
    this.updateHitTime();
    this.countDown += deltaTime;
  }
  public updateScore() {
    // 得分信息
    if (!Game.Instance().gameType.isSnooker()) {
      this.selfScore.active = false;
      this.oppoScore.active = false;
      return;
    }
    this.selfScore.active = true;
    this.oppoScore.active = true;
    const stext = this.selfScore.getChildByName('Text').getComponent(Label);
    const otext = this.oppoScore.getChildByName('Text').getComponent(Label);
    const sscore = Game.Instance().playUsers[0].score;
    const oscore = Game.Instance().playUsers[1].score;
    stext.string = `${sscore}`;
    otext.string = `${oscore}`;
    if (this.scoreTime < 30) {
      if (this.scoreSide === 0) {
        this.selfScore.getChildByName('Text').getPosition(this.pos);
        this.pos.y = this.pos.y + this.scoreTime;
        this.selfScore.getChildByName('Text').setPosition(this.pos);
        stext.string = `${sscore - this.scoreDiff}`;
      } else {
        this.oppoScore.getChildByName('Text').getPosition(this.pos);
        this.pos.y = this.pos.y + this.scoreTime;
        this.oppoScore.getChildByName('Text').setPosition(this.pos);
        otext.string = `${oscore - this.scoreDiff}`;
      }
    } else {
      this.selfScore.getChildByName('Text').setPosition(this.selfScorePos);
      this.oppoScore.getChildByName('Text').setPosition(this.oppoScorePos);
    }
  }
  public updateHitTime() {
    const sctx = this.selfComponent.getChildByName('DrawGraphics').getComponent(Graphics);
    const octx = this.oppoComponent.getChildByName('DrawGraphics').getComponent(Graphics);
    sctx.clear(); octx.clear();
    
    // 耗时信息, 已经
    if (!BilliardGame.Instance().actionStage.isCostTimeStage()) {
      this.selfComponent.getChildByName('TimeParticle').active = false;
      this.oppoComponent.getChildByName('TimeParticle').active = false;
      return;
    }
    if (Game.Instance().battleCate.isFancyBattle() || Game.Instance().battleCate.isEndlessBattle()) {
      this.selfComponent.getChildByName('TimeParticle').active = false;
      this.oppoComponent.getChildByName('TimeParticle').active = false;
      return;
    }
    var ct = UserNavigation.MaxUserTime - Game.Instance().getCurrentUserCostTime();
    if (ct <= 10 && this.countDown >= 1) {
      SoundManager.Instance().playCountDown();
      this.countDown = 0;
    }
    if (ct <= 0) {
      Game.Instance().currentUserTimeout();
      BilliardGame.Instance().endGame();
      EventManager.Instance().Emit('EndGameEvent', {});
      return;
    }

    if (Game.Instance().isSelftHitBall()) {
      const pts = this.calcuDrawCountTime(ct, 32);
      this.drawCountTimeLine(sctx, pts);
      if (pts.length > 0) {
        this.selfComponent.getChildByName('TimeParticle').setPosition(pts[0].x, pts[0].y, 0);
        this.selfComponent.getChildByName('TimeParticle').active = true;
        this.oppoComponent.getChildByName('TimeParticle').active = false;
      }
    } else {
      const pts = this.calcuDrawCountTime(ct, 32);
      this.drawCountTimeLine(octx, pts);
      if (pts.length > 0) {
        this.oppoComponent.getChildByName('TimeParticle').setPosition(pts[0].x, pts[0].y, 0);
        this.oppoComponent.getChildByName('TimeParticle').active = true;
        this.selfComponent.getChildByName('TimeParticle').active = false;
      }
    }
  }
  // 无尽模式 和 花式闯关 没有对手
  public hideOppoCommponent() {
    if (Game.Instance().battleCate.isEndlessBattle()) {
      this.oppoComponent.active = false;
    } else if (Game.Instance().battleCate.isFancyBattle()) {
      this.oppoComponent.active = false;
    } else {
      this.oppoComponent.active = true;
    }
  }
  public addUserScore(name: string, data: {side: number, score: number}) {
    if (!Game.Instance().gameType.isSnooker()) {
      return;
    }
    SoundManager.Instance().playAddScore();
    this.scoreDiff = data.score;
    this.scoreSide = data.side;
    this.scoreTime = 0;
  }
  // 剩余的时间ctime
  private calcuDrawCountTime(ctime: number, width: number) {
    const inteval = UserNavigation.MaxUserTime / 4;
    const pts = [
      new Vec2(-width, width), new Vec2(width, width),
      new Vec2(width, -width), new Vec2(-width, -width),
      new Vec2(-width, width),
    ];
    if (ctime <= 0) {
      return [];
    }
    if (ctime > 3 * inteval && ctime <= 4 * inteval) {
      pts[0].x = -width + 2 * width * (4 * inteval - ctime) / inteval;
      return pts;
    }
    if (ctime > 2 * inteval && ctime <= 3 * inteval) {
      pts[1].y = width - 2 * width * (3 * inteval - ctime) / inteval;
      return [pts[1], pts[2], pts[3], pts[4]];
    }
    if (ctime > inteval && ctime <= 2 * inteval) {
      pts[2].x = width - 2 * width * (2 * inteval - ctime) / inteval;
      return [pts[2], pts[3], pts[4]];
    }
    if (ctime > 0 && ctime <= inteval) {
      pts[3].y = -width + 2 * width * (inteval - ctime) / inteval;
      return [pts[3], pts[4]];
    }
    return pts;
  }
  // 绘制线段
  private drawCountTimeLine(ctx: Graphics, pts: Vec2[]) {
    ctx.lineWidth = 5;
    ctx.strokeColor = Color.RED;
    for (var i=1; i<pts.length; i++) {
      ctx.moveTo(pts[i-1].x, pts[i-1].y);
      ctx.lineTo(pts[i].x, pts[i].y);
    }

    ctx.stroke();
  }
}

